#include <stdio.h>

typedef struct{
    unsigned char simbolo;
    unsigned int apariciones;
    unsigned int valido;
    void* padre;
    void* izq;
    void* der;
} __attribute__ ((__packed__)) nodo_arbol_t;

typedef struct{
        nodo_arbol_t *nodo_arbol;
        void *sig;
} __attribute__ ((__packed__)) nodo_lista_t;

typedef struct{
    unsigned int codigo;
    unsigned int codigo_rev;
    unsigned int long_codigo;
    unsigned int valido;
} __attribute__ ((__packed__)) codigo_t;

typedef struct{
    unsigned int tam_original;
    unsigned int long_codificacion;
    unsigned int cant_codigos;
    unsigned int offset_codificacion;
} __attribute__ ((__packed__)) oc2_header_t;

typedef struct{
    unsigned char simbolo;
    unsigned int codigo;
    unsigned int long_codigo;
} __attribute__ ((__packed__)) codificacion_t;

void mostrar_nodo_arbol_t(nodo_arbol_t *n){
	printf("La pos de mem: %p \n", n);
	printf("simbolo: %c \n", (*n).simbolo);
	printf("apariciones: %d \n", (*n).apariciones);
	printf("valido: %d \n", (*n).valido);
	printf("ptr_padre: %p \n", (*n).padre);
	printf("ptr_izq: %p \n", (*n).izq);
	printf("ptr_der: %p \n", (*n).der);
}

void mostrar_nodo_lista_t(nodo_lista_t *n){
	printf("La pos de mem: %p \n", n);
	printf("ptr_nodo_arbol: %p \n", (*n).nodo_arbol);
	printf("ptr_sig: %p \n", (*n).sig);
	printf("El contenido del nodo arbol: \n");
	mostrar_nodo_arbol_t((*n).nodo_arbol);
}

void mostrar_codigo_t(codigo_t *c){
	printf("La pos de mem: %p \n", c);
	printf("codigo: %d \n", (*c).codigo);
	printf("codigo_rev: %d \n", (*c).codigo_rev);
	printf("long_codigo: %d \n", (*c).long_codigo);
	printf("valido: %d \n", (*c).valido);
}

void mostrar_oc2_header_t(oc2_header_t *h){
	printf("La pos de mem: %p \n", h);
	printf("tam_original: %d \n", (*h).tam_original);
	printf("long_codificacion: %d \n",(*h).long_codificacion);
	printf("cant_codigos: %d \n",(*h).cant_codigos);
	printf("offset_codificacion: %d \n",(*h).offset_codificacion);
}

void mostrar_codificacion_t(codificacion_t *c){
	printf("La pos de mem: %p \n", c);
	printf("simbolo: %c \n", (*c).simbolo);
	printf("codigo: %d \n", (*c).codigo);
	printf("long_codigo: %d \n", (*c).long_codigo);
}

void mostrar_lista(nodo_lista_t *n){
	nodo_lista_t *temp = n;
	int num = 0;
	while(temp){
		printf("El nodo numero: %d \n", num);
		mostrar_nodo_lista_t(temp);
		printf("\n");
		temp = (*temp).sig;
		num++;
	}
}

void mostrar_arbol(nodo_arbol_t *n){
	if (n){
		mostrar_nodo_arbol_t(n);
		printf("\n");
		nodo_arbol_t * arbol_izq = (*n).izq;
		nodo_arbol_t * arbol_der = (*n).der;
		mostrar_arbol(arbol_izq);
		mostrar_arbol(arbol_der);
	}
}

void setear_nodo_arbol_t(nodo_arbol_t *n, unsigned char simbolo, unsigned int apariciones, unsigned int valido, void* padre, void* izq, void* der){
	(*n).simbolo = simbolo;
	(*n).apariciones = apariciones;
	(*n).valido = valido;
	(*n).padre = padre;
	(*n).izq = izq;
	(*n).der = der;
}

void setear_nodo_lista_t(nodo_lista_t *n, nodo_arbol_t *nodo_arbol, void *sig){
	(*n).nodo_arbol = nodo_arbol;
	(*n).sig = sig;
}

void setear_codigo_t(codigo_t *c, unsigned int codigo, unsigned int codigo_rev, unsigned int long_codigo, unsigned int valido){
	(*c).codigo = codigo;
	(*c).codigo_rev = codigo_rev;
	(*c).long_codigo = long_codigo;
	(*c).valido = valido;
}

void setear_codificacion_t(codificacion_t *c, unsigned char simbolo, unsigned int codigo, unsigned int long_codigo){
	(*c).simbolo = simbolo;
	(*c).codigo = codigo;
	(*c).long_codigo = long_codigo;
}

void setear_oc2_header_t(oc2_header_t *h, unsigned int tam_original, unsigned int long_codificacion, unsigned int cant_codigos, unsigned int offset_codificacion ){
	(*h).tam_original = tam_original;
	(*h).long_codificacion = long_codificacion;
	(*h).cant_codigos = cant_codigos;
	(*h).offset_codificacion = offset_codificacion;
}
